package com.zzr.demo.redis.II.service.impl;

import com.zzr.demo.redis.II.service.PipelineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author: xiaomi
 * @date: 2021/10/13
 * @description:
 */
@Service
@Slf4j
public class PipelineServiceImpl implements PipelineService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public void batchCommand() {
        //NOTEME results 会得到各个命令的结果（已经被框架封装好了）
        List<Object> results = stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                //NOTEME 客户端无法在pipeline 中切换数据库；否则会报错！——说的是切换数据库连接就要切换，不允许这样
//                connection.select(3);
                StringRedisConnection stringRedisConn = (StringRedisConnection) connection;
                String listName = "testList";
                String res = "";
                for (int i = 0; i < 10; i++) {
                    Long aLong = stringRedisConn.lPush(listName, "1");
                    //NOTEME 居然都是返回 null 也就是不能期望 redis 在 pipeline 的单条命令中有所返回
                    log.info("i:{},return:{}", i, aLong);
                    res += aLong + ",";
                }

                return null;
            }
        });
        //输入各个命令执行的结果
        for (Object result : results) {
            log.info("result:{}", result);
        }
    }

    @Override
    public void doTransaction() {
        List<Object> results = stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                //1.开启事务
                connection.multi();
                connection.set("title".getBytes(), "hand in hand".getBytes());
                connection.sAdd("fruits-ts".getBytes(), "apple".getBytes(), "banana".getBytes());
                connection.rPush("nbs".getBytes(), "123".getBytes(), "456".getBytes());
                //2.执行事务
                connection.exec();

                return null;
            }
        });

        //输入各个命令执行的结果
        //result:[true, 2, 2]
        for (Object result : results) {
            log.info("result:{}", result);
        }
        //192.168.56.10:6379[3]> get title
        //"hand in hand"
        //192.168.56.10:6379[3]> scan fruits-ts 0
        //(error) ERR invalid cursor
        //192.168.56.10:6379[3]> sscan fruits-ts 0
        //1) "0"
        //2) 1) "banana"
        //   2) "apple"
        //192.168.56.10:6379[3]> lrange nbs 0 -1
        //1) "123"
        //2) "456"
    }
}
